﻿package igz.fleaxy.css 
{
	import com.adobe.serialization.json.JSON;
	import flash.filters.BevelFilter;
	import flash.filters.BitmapFilter;
	import flash.filters.BlurFilter;
	import flash.filters.DropShadowFilter;
	import flash.filters.GlowFilter;
	import flash.text.StyleSheet;
	import igz.fleaxy.Fleaxy;
	import igz.fleaxy.util.ObjectUtil;
	
	/**
	 * @author Intelygenz | www.intelygenz.com
	 * 
	 * Clase encargada de gestionar todo lo relacionado con los estilos en CSS
	 */
	public class CssManager {
		
		// Estas son todas las correspondencias de propiedades soportadas por flash
		//static private const _STYLE_PROPERTIES : Object = {
			//"color" : "color",
			//"display" : "display",
			//"font-family" : "fontFamily",
			//"font-size" : "fontSize",
			//"font-style" : "fontStyle",
			//"font-weight" : "fontWeight", 
			//"kerning" :  "kerning", 
			//"leading" :  "leading", 
			//"letter-spacing" : "letterSpacing", 
			//"margin-left" :  "marginLeft", 
			//"margin-right" : "marginRight", 
			//"text-align"      : "textAlign", 
			//"text-decoration" : "textDecoration", 
			//"text-indent" :  "textIndent"
		//}
		

		/**
		 * Estilos propios de Fleaxy para las Hojas de estilo
		 */

		// Globales
		static public const $STYLE_JSON_ROOT : String = "igz-css";

		/**
		 * @example "color":"0xFF0000", "imageUri":"./bg.jpg", "embedImage":"ku03_ImageLibrary.$BtnUp"
		 */
		static public const $STYLE_BACKGROUND : String = "igzBackground";
		/**
		 * @example #FFFFFF
		 */
		static public const $STYLE_COLOR	  : String = "igzColor";
		/**
		 * @example 20
		 */
		static public const $STYLE_SIZE	  	  : String = "igzSize";
		/**
		 * @example 4,4,0,0
		 */
		static public const $STYLE_ROUND	  : String = "igzRound";
		/**
		 * @example 0.0 - 1.0
		 */
		static public const $STYLE_ALPHA	  : String = "igzAlpha";
		/**
		 * @example 0 - 150
		 */
		static public const $STYLE_FIXWIDTH	  : String = "igzFixWidth";
		/**
		 * @example #FF0000
		 */
		static public const $STYLE_BORDER : String = "igzBorder";
		/**
		 * @example 0.0 - 1.0
		 */
		static public const $STYLE_BORDER_ALPHA : String = "igzBorderAlpha";
		/**
		 * @example 0 - 255
		 */
		static public const $STYLE_BORDER_THICKNESS : String = "igzBorderThickness";

		// TextUi
		/**
		 * @example advanced ó normal
		 */
		static public const $STYLE_ANTIALIAS : String = "igzAntialias";

		// Filters
		/**
		 * @example distance:4, angle:45, highlightColor:16777215, highlightAlpha:1, shadowColor:0, shadowAlpha:1, blurX:4, blurY:4, strength:1, quality:1, type:"inner", knockout: false
		 */
		static public const $STYLE_FILTER_BEVEL	 	 : String = "igzFilterBevel";
		/**
		 * @example distance:4, angle:45, color:0, alpha:1, blurX:4, blurY:4, strength:1, quality:1, inner:false, knockout:false, hideObject:false
		 */
		static public const $STYLE_FILTER_DROPSHADOW : String = "igzFilterDropshadow";
		static public const $STYLE_FILTER_GLOW	 	 : String = "igzFilterGlow";
		static public const $STYLE_FILTER_BLUR		 : String = "igzFilterBlur";

		//private var _StyleSheets:Object;

		private var _DefaultStyleSheet : StyleSheet;
		public function get $Default() : StyleSheet {
			//return $GetStyleSheet(Fleaxy.$Current.$ConfigurationManager.$DefaultCssName);
			return _DefaultStyleSheet;
		}

		/**
		 * TODO vacio
		 */
		public function CssManager() {
			//_StyleSheets = new Object();
		}

		/**
		 * Función encargada de cargar el CSS a partir de un fichero
		 * 
		 * @param	p_css URL del fichero
		 * 
		 * @param	p_nameCss nombre del fichero @default null
		 */
		public function $LoadCss(p_css:String, p_nameCss:String=null) : void {
			//_StyleSheets[p_nameCss] = new StyleSheet();
			//_StyleSheets[p_nameCss].parseCSS( p_css );
			_DefaultStyleSheet = new StyleSheet();
			_DefaultStyleSheet.parseCSS( p_css );
		}

		/**
		 * 
		 * @param	p_nameCss // no aplica
		 * @return DefaultStyleSheet
		 */
		public function $GetStyleSheet(p_nameCss:String ) : StyleSheet {
			//return (_StyleSheets[p_nameCss] as StyleSheet);
			return _DefaultStyleSheet;
		}
		
		/**
		 * Obtiene el valor deseado de un estilo de una determinada CSS
		 * 
		 * @param	p_style Nombre del estilo
		 * @param	p_styleProperty Nombre de la propiedad del estilo
		 * @param	p_css Hoja de estilo, si no se especifica coge la que haya por defecto
		 * 
		 * @return Una objeto que contiene el valor del estilo deseado, en caso de no existir devuelve null
		 * 
		 * @example
		 * 
		 * var myStyle:Object = Fleaxy.$Current.$CssManager.$GetStyleValue("enlace", "fontFamily");
		 * 
		 * IMPORTANTE : Internamente cambia el nombre de la propiedad de estilo con guiones a camel case ( "font-color" -> "fontColor" )
		 */
		public function $GetStyleValue(p_style:String, p_styleProperty:String, p_css:String = null) : String {
			//var css:StyleSheet = this.$Default;
			//if ( p_css != null ) {
				//css = this.$GetStyleSheet(p_css);
			//}
			var css:StyleSheet = _DefaultStyleSheet;

			var styleValue:String = null;
			var style:Object = css.getStyle("." + p_style );
			
			if ( style.hasOwnProperty(p_styleProperty) ) {
				styleValue = style[p_styleProperty];
			}

			if ( styleValue != null && styleValue.indexOf("#")!=-1) {
				styleValue = styleValue.replace("#", "0x");
			}

			return styleValue;
		}

		/**
		 *  Devuelve el estilo de un determinado elemento
		 * 
		 * TODO revisar
		 * 
		 * @param	p_style nombre del estilo 
		 * @param	p_styleProperty propiedad
		 * @param	p_css css @default null
		 * @return  Json decodeado con el estilo del objeto
		 */
		public function $GetStyleObject(p_style:String, p_styleProperty:String, p_css:String = null) : Object {
			var styleValue:String = $GetStyleValue(p_style, p_styleProperty, p_css);
			var filterJSON:Object;
			if ( styleValue != null ) {
				styleValue = " { \"" + CssManager.$STYLE_JSON_ROOT + "\" : { " + styleValue + " } } ";
				filterJSON = JSON.decode(styleValue);
			}
			return filterJSON;
		}

		/**
		 * Devuvelve los filtros de estilo de un determinado elemento
		 * TODO revisar
		 * 
		 * @param	p_style Nombre del estilo 
		 *
		 * @param	p_css tipo del estilo @default null
		 * @return array con todos los filtros
		 */
		public function $GetStyleFilters(p_style:String, p_css:String = null) : Array {
			var typeFilters:Array = [CssManager.$STYLE_FILTER_BEVEL
									,CssManager.$STYLE_FILTER_DROPSHADOW
									,CssManager.$STYLE_FILTER_GLOW
									,CssManager.$STYLE_FILTER_BLUR
									];
			var filters:Array = [];

			var filterJSON:Object;
			var filter:BitmapFilter;

			for ( var f:uint = 0; f < typeFilters.length; f++ ) {
				filterJSON = $GetStyleObject(p_style, typeFilters[f], p_css)
				switch ( typeFilters[f] ) {
					case CssManager.$STYLE_FILTER_BEVEL :
						filter = new BevelFilter();
						break;
					case CssManager.$STYLE_FILTER_DROPSHADOW : 
						filter = new DropShadowFilter();
						break;
					case CssManager.$STYLE_FILTER_GLOW :
						filter = new GlowFilter();
						break;
					case CssManager.$STYLE_FILTER_BLUR :
						filter = new BlurFilter();
						break;
				}
				
				if ( filterJSON != null ) {
					ObjectUtil.$Merge(filterJSON[CssManager.$STYLE_JSON_ROOT], filter);
					filters.push(filter);
				}
			}
			return filters;
		}
		
		
		/**
		 * Add a new style to the stylesheet
		 * 
		 * @example var styleName : String = new Date().getTime().toString();
		 *			Fleaxy.$Current.$CssManager.$AddStyles("." + styleName + "{ font-family: Verdana; font-size: 40; color:#00ff00; }" );
		 * 
		 * @param	p_cssText The CSS text to parse (a string).
		 * @param	p_cssName Name style
		 */
		public function $AddStyles ( p_cssText:String, p_cssName:String = null ) : void {
			p_cssName = (p_cssName == null) ? Fleaxy.$Current.$ConfigurationManager.$DefaultCssName : p_cssName;
			
			var style:StyleSheet = $GetStyleSheet( p_cssName );
			style.parseCSS( p_cssText );
		}

	}
	
}